#include <Windows.h>
#include <string>

#include "m8sdkhelper.h"

using namespace std;

typedef int (*start_app_func) (int, char**);

static bool check_instance_exists(const wstring& id)
{
	::CreateMutex(NULL, TRUE, id.c_str());

	if (::GetLastError() == ERROR_ALREADY_EXISTS)
	{
		//Already exists
		::PostMessage(HWND_BROADCAST,
					  ::RegisterWindowMessage(id.c_str()),
					  NULL,
					  NULL);

		return true;
	}

	return false;
}

//switch
//-nocheck		do not check multiple instances
//-dial			just connect gprs then exit
//-splash		just show the splash then exit
//-refresh		refresh mode

int main(int argc, char *argv[])
{
	::CoInitializeEx(NULL, COINIT_MULTITHREADED);

	wchar_t dest[MAX_PATH];
	mbstowcs(dest, argv[0], MAX_PATH);
	wstring path(dest);

	size_t pos = path.find_last_of(L'\\');
	size_t pos2 = path.find_last_of(L'.');

	wstring dir = path.substr(0, pos + 1);
	//wstring filename = path.substr(pos + 1, -1);
	wstring basename = path.substr(pos + 1, pos2 - pos - 1);
	wstring dllname = basename + L".dll";
	wstring splash1 = dir + L"splash.png";
	wstring splash2 = dir + basename + L"\\splash.png";


	HMODULE helper_dll = ::LoadLibrary(L"m8sdkhelper.dll");

	m8sdk_draw_splash_func draw_func =
			(m8sdk_draw_splash_func)::GetProcAddressA(helper_dll,
													  "m8sdk_draw_splash");
	m8sdk_redraw_func redraw_func =
			(m8sdk_redraw_func)::GetProcAddressA(helper_dll,
												 "m8sdk_redraw");
	m8sdk_connect_gprs_func connect_func =
			(m8sdk_connect_gprs_func)::GetProcAddressA(helper_dll,
													   "m8sdk_connect_gprs");

	//check args
	bool dial = false;
	bool nocheck = false;
	bool splash = false;
	bool refresh = false;

	for (int i = 1; i < argc; ++i)
	{
		string arg(argv[i]);

		if (arg == string("-nocheck"))
			nocheck = true;
		else if (arg == string("-dial"))
			dial = true;
		else if (arg == string("-splash"))
			splash = true;
		else if (arg == string("-refresh"))
			refresh = true;
	}

	//dial?
	if (dial)
	{
		if (connect_func)
			connect_func();

		return 0;
	}

	//check?
	if (!nocheck)
	{
		if (check_instance_exists(path))
			return 0;
	}

	//draw splash
	if (!refresh && draw_func)
	{
		if (!draw_func((wchar_t*)splash2.c_str()))
		{
			draw_func((wchar_t*)splash1.c_str());
		}
	}

	if (splash && redraw_func)
	{
		::Sleep(4000);

		return 0;
	}

	//start app
	HMODULE start_dll = ::LoadLibrary(dllname.c_str());
	start_app_func start_func = (start_app_func)
								::GetProcAddressA(start_dll, "main");

	//draw splash again
	if (!refresh && draw_func)
	{
		if (!draw_func((wchar_t*)splash2.c_str()))
		{
			draw_func((wchar_t*)splash1.c_str());
		}
	}

	int result = 0;

	if (start_func)
		result = start_func(argc, argv);
	else
		result = -1;

	return result;
}

